package cn.com.doone.common.uc.oauth.validator;

import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.oltu.oauth2.as.request.OAuthAuthzRequest;
import org.apache.oltu.oauth2.as.request.OAuthRequest;
import org.apache.oltu.oauth2.common.error.OAuthError;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.OAuthResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.com.doone.common.uc.domain.oauth.ClientDetails;
import cn.com.doone.common.uc.utils.HttpClientUtil;

public class ExistTokenClientDetailValidator extends AbstractClientDetailsValidator{
	
	private static final Logger LOG = LoggerFactory.getLogger(ExistTokenClientDetailValidator.class);

	public  ExistTokenClientDetailValidator(OAuthRequest oauthRequest,HttpServletRequest request) {
		super(oauthRequest,request);
	}

	@Override
	public OAuthResponse validateSelf(ClientDetails clientDetails) throws OAuthSystemException {

        //validate redirect_uri
        final String redirectURI = HttpClientUtil.decodeURIComponent(HttpClientUtil.decodeURIComponent(oauthRequest.getRedirectURI()));
        if (redirectURI == null || redirectURI.indexOf(clientDetails.getRedirectUri()) != 0) {
            LOG.debug("Invalid redirect_uri '{}' by response_type = 'code', client_id = '{}'", redirectURI, clientDetails.getClientId());
            return invalidRedirectUriResponse();
        }
        
        //validate token
        final String token = cn.com.doone.common.uc.utils.StringUtils.isNull(oauthRequest.getParam("token"))?request.getHeader("token"):oauthRequest.getParam("token");
        if(cn.com.doone.common.uc.utils.StringUtils.isNull(token)) {
        	return OAuthResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
        			.setError(OAuthError.CodeResponse.INVALID_REQUEST)
        			.setErrorDescription("token not found")
        			.buildJSONMessage();
        }

        //validate clientId
        final String clientId = oauthRequest.getClientId();
        if(cn.com.doone.common.uc.utils.StringUtils.isNull(clientId)) {
        	return OAuthResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
        			.setError(OAuthError.CodeResponse.INVALID_REQUEST)
        			.setErrorDescription("clientId is not found")
        			.buildJSONMessage();
        }
        
        //validate scope
        final Set<String> scopes = oauthRequest.getScopes();
        if (scopes.isEmpty() || excludeScopes(scopes, clientDetails)) {
            return invalidScopeResponse();
        }
        
        //validate state
        final String state = ((OAuthAuthzRequest) oauthRequest).getState();
        
        if (StringUtils.isEmpty(state)) {
            LOG.debug("Invalid 'state', it is required, but it is empty");
            return OAuthResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
                    .setError(OAuthError.CodeResponse.INVALID_REQUEST)
                    .setErrorDescription("Parameter 'state'  is required")
                    .buildJSONMessage();
        }

        return null;
	}
}
